package com.bridgeintelligent.tag.webserver.workflow;

import com.bridgeintelligent.tag.constants.ExceptionCodes;
import com.bridgeintelligent.tag.user.mgmt.pojo.User;
import com.bridgeintelligent.tag.utils.DateHelper;
import com.bridgeintelligent.tag.utils.SecurityHelper;
import com.bridgeintelligent.tag.webserver.workflow.repository.HistoryMapper;
import com.bridgeintelligent.tag.webserver.workflow.repository.InstanceMapper;
import com.bridgeintelligent.tag.webserver.workflow.repository.NodeMapper;
import com.bridgeintelligent.tag.webserver.workflow.repository.WorkflowMapper;
import com.github.pagehelper.Page;
import com.wayneleo.quickstart.framework.IDGenerator;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class SubmitterServiceImpl implements SubmitterService {

    private WorkflowMapper workflowMapper;
    private InstanceMapper instanceMapper;
    private NodeMapper nodeMapper;
    private HistoryMapper historyMapper;

    @Override
    public Instance submit(SubmitParam param) {
        //checkResourceContains(param);
        User user = getCurrentUserId();
        String ownerId =user.getUserId() ;
        Instance instance = null;
        if (StringUtils.isNotEmpty(param.getInstanceId())) {
            instance = instanceMapper.findOne(param.getInstanceId());
            checkInstanceIsThisman(instance);
        } else {
            instance = new Instance();
        }
        Workflow workflow = workflowMapper.findOne(param.getWorkflowId());
        instance.setOwner(ownerId)
                .setWorkflowId(param.getWorkflowId())
                .setWorkflowName(workflow.getName())
                .setNodeOrder(1)
                .setUpdateDate(DateHelper.currentDateTime())
                .setCurrentStatus(Status.WAITTING.code())
                .setResource(param.getResourceId());
        if (StringUtils.isEmpty(instance.getId())) {
            instance.setId(IDGenerator.gen());

            /**
             * 正常一个审批流instance只有一条数据，但是客群多次导出功能会造成多实例，所以在此处特别处理
             */
            param.setInstanceId(instance.getId());
            checkResourceContains(param);

            instanceMapper.save(instance);
        } else {

            /**
             * 正常一个审批流instance只有一条数据，但是客群多次导出功能会造成多实例，所以在此处特别处理
             */
            param.setInstanceId(instance.getId());
            checkResourceContains(param);

            instanceMapper.update(instance);
        }

        List<Node> nodes = nodeMapper.findAll(instance.getWorkflowId());
        History history = new History()
                .setId(IDGenerator.gen())
                .setInstanceId(instance.getId())
                .setNodeId(nodes.get(0).getId())
                .setStatus(Status.WAITTING.code())
                .setApproverId(user.getUserId())
                .setApproverName(user.getName())
                .setUpdateDate(DateHelper.currentDateTime());
        historyMapper.save(history);

        return instance;
    }

    @Override
    public Instance fetchOne(String instanceId) {
        Instance instance = instanceMapper.findOne(instanceId);
        if (instance == null) {
            throw new WorkflowException(ExceptionCodes.WORKFLOW_20002.args(instanceId));
        }
        Node node = nodeMapper.findOne(instance.getWorkflowId(), instance.getNodeOrder());
        List<History> histories = historyMapper.findHistories(instanceId);
        instance.setNode(node);
        instance.setHistories(histories);
        return instance;
    }

    @Override
    public Page<Instance> fetchAll(FetchAllParam param) {
        InstanceMapper.AllForSubmitter dbParam = new InstanceMapper.AllForSubmitter().setOwner(getCurrentUserId().getUserId())
                                                                                     .setContainsDeleted(param.isContainsDeleted())
                                                                                     .setPageNum(param.getPageNum())
                                                                                     .setPageSize(param.getPageSize());
        if (param.getWorkflowIds() != null || param.getWorkflowIds()
                                                   .size() > 0) {
            dbParam.setWorkflowIds(param.getWorkflowIds());
        }
        return instanceMapper.findAllForSubmitter(dbParam);
    }

    @Override
    public Map<String, Instance> fetchByResources(FetchByResourcesParam param) {
        Map<String, Instance> instanceMapping = new HashMap<>();
        if (param.getResourceIds() == null || param.getResourceIds()
                                                   .size() < 1) {
            return instanceMapping;
        }
        Map<String, Instance> map = instanceMapper.findByResources(new InstanceMapper.FindByResourcesParam().setResourceIds(param.getResourceIds())
                                                                                                            .setContainsDeleted(param.isContainsDeleted())
                                                                                                            .setCurrentStatus(param.getCurrentStatus()));
        for (Map.Entry<String, Instance> e : map.entrySet()) {
            String resource = e.getValue()
                               .getResource();
            System.out.println("测试打印================0" + resource);
            System.out.println("测试打印================0" + e.getValue()
                                                          .getId());
        }
        instanceMapping.putAll(instanceMapper.findByResources(new InstanceMapper.FindByResourcesParam().setResourceIds(param.getResourceIds())
                                                                                                       .setContainsDeleted(param.isContainsDeleted())
                                                                                                       .setCurrentStatus(param.getCurrentStatus())));
        return instanceMapping;
    }

    private User getCurrentUserId() {
        User user = SecurityHelper.currentUser();
        return user;
    }

    private void checkResourceContains(SubmitParam param) {
        List<Object> results = instanceMapper.checkByResource(new InstanceMapper.CheckByResourceParam().setResource(param.getResourceId())
                                                                                                       .setWorkflowId(param.getWorkflowId())
                                                                                                       .setContainsDeleted(false)
                                                                                                       .setCurrentStatus(Status.WAITTING.code())
                                                                                                        .setInstanceId(param.getInstanceId()) );
        if (results != null && results.size() > 0) {
            throw new WorkflowException(ExceptionCodes.WORKFLOW_20007);
        }
    }

    private void checkInstanceIsThisman(Instance instance) {
        String ownerId = getCurrentUserId().getUserId();
        if (!ownerId.equals(instance.getOwner())) {
            throw new WorkflowException(ExceptionCodes.WORKFLOW_20004.args(instance.getId(), ownerId));
        }
    }
}
